﻿using System;
using System.Net;
using System.Net.Sockets;
using System.Runtime.InteropServices;
using System.Text;
using static System.Net.Mime.MediaTypeNames;
using System.Text.Unicode;

namespace multi_thread_impl_http {

    class Application
    {

         static void Main()
        {

            Socket server = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
           
            server.Bind(new IPEndPoint(IPAddress.Any,19999));

            server.Listen();

          
                acceptConnection(server);

           

            Console.ReadLine();
        }

         static void  acceptConnection(Socket server) {
            while (true)
            {
                Socket client =  server.Accept();

                requestHandler(client);
                /*Task.Run(() =>
                {

                    
                });*/
            }
        }

        async static Task requestHandler(Socket client) {

            byte[] bytes = new byte[11024];

            while (true)
            {

                if (!client.Poll(100, SelectMode.SelectWrite))
                {
                    // 如果没有这个函数，那么就是轮询模式
                    // 轮询会把cpu跑满
                    continue;
                }

                int received = await client.ReceiveAsync(bytes);

                

                var data = Encoding.UTF8.GetString(bytes, 0, received);

                string[] requestLines = data.Split('\n');

                string[] firstLine = requestLines[0].Split(' ');

                if (firstLine.Length < 2)
                {

                    client.Send(Encoding.UTF8.GetBytes("HTTP/1.1 405 Error"));

                    Console.Error.WriteLine("http请求行异常" + firstLine);
                    continue;
                }

                string requestPath = firstLine[1];

                //string requestContent = requestPath.Substring(requestPath.IndexOf("/")+1);

                if ("/".Equals(requestPath))
                {
                    requestPath = "/index.html";
                }

                requestPath = requestPath.Replace("/", "\\");

                string resp = null;
                string contentType = "";

                if (requestPath.Contains("css"))
                {
                    contentType = "text/css";

                }
                else if (requestPath.Contains("js"))
                {
                    contentType = "text/javascript";
                }
                else
                {
                    contentType = "text/html";
                }

                try
                {
                    // Open the text file using a stream reader.
                    using StreamReader reader = new("C:\\Users\\luo\\RiderProjects\\tour\\multi_thread_impl_http\\multi_thread_impl_http\\wwwroot" + requestPath);

                    // Read the stream as a string.
                    string body = reader.ReadToEnd();


                    resp = $@"HTTP/1.1 200 OK
Connection: keep-alive
Content-Type: {contentType}; charset=UTF-8
Content-Length: {body.Length}

" + body;
                    Console.WriteLine(resp);
                    await client.SendAsync(Encoding.UTF8.GetBytes(resp));
                }
                catch (IOException e)
                {
                    Console.WriteLine("The file could not be read:");
                    Console.WriteLine(e.Message);
                    await client.SendAsync(Encoding.UTF8.GetBytes("HTTP/1.1 404 NotFound"));
                }



            }


        }
    }


}
